package org.swxjava.assembler;

import org.swxjava.util.Log;
import org.swxjava.util.LogFactory;
import org.swxjava.util.StringUtils;

import org.swxjava.assembler.avm1.SwxResult;

public class SwxAssembler {
	/** Logger */
	private static final Log LOG = LogFactory.getLog(SwxAssembler.class);

	public static final String VAR_RESULT = "726573756C74";

	private ConverterManager converterManager = null;
	private String url = null;
	private boolean debug = false;
	private boolean allowDomain = false;
	private int compressionLevel = Compressor.DEFAULT_COMPRESSION_LEVEL;

	public byte[] compile(Object data) throws MarshallException {
		if (converterManager == null) {
			throw new IllegalStateException("ConverterManager was null.");
		}
		byte[] swfBytes = null;

		ObjectCompiler oc = converterManager.convert(data);
		SwxResult result = new SwxResult(oc);
		// Allow domain? If so add allow domain statement to the SWF
		result.setAllowDomain(allowDomain);
		result.setUrl(url);
		// Debug? If so, add the analyzer connector to the SWF
		result.setDebug(debug);

		// Create the DoAction tag
		String doActionBlock = result.toString();

		// Create the whole SWF
		String headerType = Constants.FILE_UNCOMPRESSED_SWF;
		String swf = headerType + Constants.HEADER + doActionBlock
				+ Constants.ACTION_SHOW_FRAME + Constants.ACTION_END_SWF;
		String swfSizeInBytes = StringUtils.getStringLengthInBytesHex(swf, 4);
		swf = swf.replaceAll("LLLLLLLL", swfSizeInBytes);

		LOG.debug("Output bytecode : " + swf);

		swfBytes = StringUtils.convertHexStringToBytes(swf);

		LOG.debug("Compression Level : " + compressionLevel);
		LOG.debug("Uncompressed size of SWF: " + swfBytes.length + " bytes.");

		swfBytes = Compressor.compress(swfBytes, swf.length() / 2,
				compressionLevel);
		LOG.debug("Compressed size of SWF: " + swfBytes.length + " bytes.");

		return swfBytes;
	}

	public ConverterManager getConverterManager() {
		return converterManager;
	}

	public void setConverterManager(ConverterManager converterManager) {
		this.converterManager = converterManager;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public boolean isAllowDomain() {
		return allowDomain;
	}

	public void setAllowDomain(boolean allowDomain) {
		this.allowDomain = allowDomain;
	}

	public int getCompressionLevel() {
		return compressionLevel;
	}

	public void setCompressionLevel(int compressionLevel) {
		this.compressionLevel = compressionLevel;
	}

	public boolean isDebug() {
		return debug;
	}

	public void setDebug(boolean debug) {
		this.debug = debug;
	}
}
